#pragma once

#include "../gl/gl_view.h"
#include "../manager/notification_manager.h"
#include "space.h"

OPEN_JLIB_NS


struct Director : public GLView::Listener, public NotificationManager {

  Director () noexcept;
  ~Director () override;

  void startup (GLView *gl, Space *root, const GLView::WindowConfig &config);



  void onClose () override;
  void onResize (Vec2i size) override;
  void onResume () override;
  void onPause () override;

  void onMousePress (MouseEvent::Button code) override;
  void onMouseRelease (MouseEvent::Button code) override;
  void onMouseMove (Vec2 location) override;
  void onMouseEnter () override;
  void onMouseLeave () override;
  void onMouseScroll (Vec2 offset) override;

  void onKeyPress (KeyEvent::Key code) override;
  void onKeyRepeat (KeyEvent::Key code) override;
  void onKeyRelease (KeyEvent::Key code) override;

  void onTouchDown (s32 id, Vec2 location) override;
  void onTouchMove (const std::vector<s32> &ids, const std::vector<Vec2> &locations) override;
  void onTouchUp (s32 id, Vec2 location) override;
  void onTouchCancel (s32 id) override;

  inline void setTimeScale (f32 scale) noexcept {
    _timeScale = scale;
  }

  inline void useRealTime () noexcept {
    _flags |= UseRealDeltaTime;
  }

  inline void useVirtualTime () noexcept {
    _flags &= ~UseRealDeltaTime;
  }

  inline f32 getTimeScale () const noexcept { return _timeScale; }
  inline bool isRealTimeUsed () const noexcept { return (_flags & UseRealDeltaTime) != 0; }

private:
  enum Flag : u32 {
    ShouldCloseWindow = 1,
    UseRealDeltaTime = ShouldCloseWindow << 1,
  };

  NotificationManager _notificationManager;

  GLView *_view = nullptr;
  Ptr<Space> _root;
  f32 _timeScale = 1.0F;
  u32 _flags = 0;
};


CLOSE_JLIB_NS
